package com.apkcore.core.mvi

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.launch

/**
 * 封装一个通用的MVI
 */
interface IUIState

interface IUiIntent

//
//abstract class BaseViewModel<UiState : IUIState, UiIntent : IUiIntent> : ViewModel() {
//
//    private val _uiStateFlow = MutableStateFlow(initUIState())
//    val uiStateFlow: StateFlow<UiState> = _uiStateFlow
//
//    private val intentChannel: Channel<UiIntent> = Channel()
//
//    protected abstract fun initUIState(): UiState
//    protected abstract fun handleIntent(intent: UiIntent)
//
//    init {
//        viewModelScope.launch {
//            intentChannel.consumeAsFlow().collect {
//                handleIntent(it)
//            }
//        }
//    }
//
//    fun sendUiIntent(uiIntent: UiIntent) {
//        viewModelScope.launch {
//            intentChannel.send(uiIntent)
//        }
//    }
//
//    protected fun sendUiState(copy: UiState.() -> UiState) {
//        _uiStateFlow.update { copy(_uiStateFlow.value) }
//    }
//}

abstract class BaseViewModel<UiState : IUIState, UiIntent : IUiIntent> : ViewModel() {

    private val _uiStateFlow = MutableSharedFlow<UiState>(0, 10, BufferOverflow.DROP_OLDEST)
    val uiStateFlow = _uiStateFlow.asSharedFlow()

    // 当前的 UI 状态缓存
//    private var currentUiState: UiState = initUIState()
    private val intentChannel: Channel<UiIntent> = Channel()

//    /**
//     * 因为StateFlow必须有个初始化的状态
//     */
//    protected abstract fun initUIState(): UiState

    protected abstract suspend fun handleIntent(intent: UiIntent)

    init {
        viewModelScope.launch {
            intentChannel.consumeAsFlow().collect {
                handleIntent(it)
            }
        }
    }

    /**
     * 调用V层来调用事件
     */
    fun sendUiIntent(uiIntent: UiIntent) {
        viewModelScope.launch {
            intentChannel.send(uiIntent)
        }
    }

    /**
     * 返回给UI层，通知更新
     */
//    protected fun sendUiState(copy: UiState.() -> UiState) {
//        currentUiState = currentUiState.copy()
//        _uiStateFlow.tryEmit(currentUiState)
//    }

    protected fun sendUiState(uiState: UiState) {
        _uiStateFlow.tryEmit(uiState)
    }
}